﻿/**
 * ScrollBar Component Main Class - Created by FlashFrameLess Team OCT/2008
 *
 * @author		FabioTNT / FlashFrameLessTeam - http://www.flashframeless.com/
 * @version		1.0
 */

package com.flashframeless.components.ui.scrollBar {

	import flash.display.Stage;
	import flash.display.MovieClip;
	
	import flash.events.MouseEvent;
	import flash.events.Event;
	
	import flash.geom.Rectangle;
	
	import gs.TweenLite;
	import gs.easing.Expo;
	
	import com.flashframeless.components.ui.scrollBar.MacMouseWheel;
	
	import com.flashframeless.components.ui.scrollBar.ScrollBarEvent;
	//import com.flashframeless.components.ui.scrollBar.ExternalMouseWheelSupport;
	import com.flashframeless.math.NumberUtils;
	
	public class ScrollBar extends MovieClip {
		
		private var _bgMc		: MovieClip;
		private var _dragMc		: MovieClip;
		private var _trackMc 	: MovieClip;
		private var _scrollArea	: Rectangle;
		
		private var _topLimit	: Number;
		private var _range		: uint;
		private var _percent	: Number;
		
		//private var _mwSupport	: ExternalMouseWheelSupport;
		
		public function ScrollBar():void {			
			
			MacMouseWheel.setup( stage );
			
			setupInteractions();
			
			dispatchEvent( new Event( Event.COMPLETE ) );
			
		}
		
		private function initClips():void {
			
			_dragMc 	= dragMc;
			_trackMc 	= trackMc;
			_bgMc		= bgMc;
			
		}
		
		private function setupInteractions():void {
			
			//Init MovieClip Variables
			initClips();
			
			//Set ScrollBar Limits
			setLimits();
			
			//Active Listeners
			activeListeners();
			
		}
		
		/**
		 * Set Limits value.
		 *
		 * @param	status	Boolean
		 * @return			void
		 */
		public function setLimits() {
			
			_scrollArea = new Rectangle( _trackMc.x, _trackMc.y, 0, _trackMc.height - _dragMc.height );
			
			_topLimit = _trackMc.y;
			
			_range = _trackMc.height - _dragMc.height;
			
		}
		
		/**
		 * Active/Desactive Listeners.
		 *
		 * @param	status	Boolean
		 * @return			void
		 */
		private function activeListeners( status:Boolean = true ):void{
			
			var method:String = status ? 'addEventListener' : 'removeEventListener';			
			
			//init onOver Listener
			_dragMc[method]( MouseEvent.MOUSE_OVER, onOver 	);
			
			//init onOut Listener
			_dragMc[method]( MouseEvent.MOUSE_OUT, 	onOut 	);
			
			//init onClick Listener
			_dragMc[method]( MouseEvent.MOUSE_DOWN, onDown 	);
			
			//Mouse Whell
			parent[method]( MouseEvent.MOUSE_WHEEL, onWheeler );
			
			_dragMc.buttonMode 		= status;
			_dragMc.mouseChildren 	= !status;
			
			onOut();
			
		}
		
		/**
		 * Set Drag by Percent.
		 *
		 * @param	evt		Event
		 * @return			void
		 */
		private function setDragByPercent( percent:Number ):void {
			
			_percent = percent;
			_percent = NumberUtils.setToRange( _percent, 0, 1 );
			
			var posY = _range * _percent;

			TweenLite.to( _dragMc, .5, { 
				
				y:posY,
				ease:Expo.easeOut,
				
				onUpdate:function() {
					
					dispatchEvent( new ScrollBarEvent( ScrollBarEvent.UPDATE, _dragMc.y / _range ) );
					
				}
				
			} );
			
		}
		
		/*-------------------------------------------------------------------------------------------------*\
		|* Handlers ---------------------------------------------------------------------------------------*|
		\*-------------------------------------------------------------------------------------------------*/
		
		/**
		 * OnOver Handler.
		 *
		 * @param	evt		MouseEvent
		 * @return			void
		 */
		private function onOver( evt:MouseEvent = null ):void {
			
			//Over
			dispatchEvent( new MouseEvent( MouseEvent.MOUSE_OVER ) );
			
		}
		
		/**
		 * OnOut Handler.
		 *
		 * @param	evt		MouseEvent
		 * @return			void
		 */
		private function onOut( evt:MouseEvent = null ):void {
			
			//Out
			dispatchEvent( new MouseEvent( MouseEvent.MOUSE_OUT ) );
			
		}
		
		/**
		 * onDown Handler.
		 *
		 * @param	evt		MouseEvent
		 * @return			void
		 */
		private function onDown( evt:MouseEvent = null ):void {
			
			//Press
			
			_dragMc.stage.addEventListener( MouseEvent.MOUSE_UP, onUp, false, 0, true );
		
			_dragMc.startDrag( false, _scrollArea );
			_dragMc.addEventListener( Event.ENTER_FRAME, scroller );
			
			dispatchEvent( new Event( MouseEvent.MOUSE_DOWN ) );
			
		}
		
		/**
		 * onUp Handler.
		 *
		 * @param	evt		MouseEvent
		 * @return			void
		 */
		private function onUp( evt:MouseEvent = null ):void {
			
			//Click
			
			_dragMc.stage.removeEventListener( MouseEvent.MOUSE_UP, onUp );
			
			_dragMc.stopDrag();
			_dragMc.removeEventListener( Event.ENTER_FRAME, scroller );
			
			dispatchEvent( new Event( MouseEvent.MOUSE_UP ) );
			
		}
		
		/**
		 * onWheeler Handler.
		 *
		 * @param	evt		MouseEvent
		 * @return			void
		 */
		private function onWheeler( evt:MouseEvent ):void {
			
			_percent -= evt.delta * .03;
			
			scrollPercent = _percent;
			
		}
		
		/**
		 * Scroller Handler.
		 *
		 * @param	evt		Event
		 * @return			void
		 */
		private function scroller( evt:Event ):void {
			
			_percent = ( _dragMc.y - _trackMc.y ) / _range;
			
			dispatchEvent( new ScrollBarEvent( ScrollBarEvent.UPDATE, _percent ) );
			
		}
		
		/*-------------------------------------------------------------------------------------------------*\
		|* Getters e Setters ------------------------------------------------------------------------------*|
		\*-------------------------------------------------------------------------------------------------*/
				
		/**
		 * Combo Enabled Setter.
		 *
		 * @param	status	Boolean
		 * @return			void
		 */
		 public function set scrollEnabled( status:Boolean ) {
			
			//Active or Desactive Mouse Events
			activeListeners( status );
			
		}
		
		/**
		 * Scroll Percent Setter.
		 *
		 * @param	percent	Number
		 * @return			void
		 */
		 public function set scrollPercent( percent:Number ) {
			
			//Set DragMc by Percent Value
			setDragByPercent( percent );
			
		}
		
		/**
		 * Scroll Size Setter.
		 *
		 * @param	width	Number
		 * @param	height	Number
		 * @return			void
		 */
		 public function set size( sizeObj:Object ):void {
			
			//Set itens Width
			_bgMc.width 	= sizeObj.width - 2;
			_trackMc.width	= sizeObj.width;
			_dragMc.width	= sizeObj.width;
			
			//Set itens Height
			_bgMc.height 	= sizeObj.height - 2;
			_trackMc.height = sizeObj.height;
			
			if ( sizeObj.percent ) {
				
				_dragMc.height = Math.max( 50, Math.round( _trackMc.height * sizeObj.percent ) );
				
			}
			
		}
		
	}
	
}